home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
advancec.arc
/
GRFUSER.C
< prev
next >
Wrap
Text File
|
1992-01-24
|
31KB
|
1,200 lines
/*
* user functions for IBM PC
*
* if using the Microsoft, Lattice, or Ecosoft compiler
* which have a dos.h include file and use the int86() function
* call in place of sysint(), uncomment the #define OTHER below
*
* If using the Microsoft compiler, also uncomment the #define MICROSOFT
* and compiler this module enabling the far keyword (/Ze for MSC, /Me for CL)
* The peek() function at the end of this module requires a pointer to
* a far object.
*
* WARNING: It is the programmers responsibility to provide
* proper scaling of x,y coordinates for the type of display used.
* The original program files assume a 1024 x 1024 screen. The
* should either provide routines to scale the incoming coordinates
* to the type of graphics screen used or alter the functions in
* the other directories to conform to the type of screen.
*
*/
/* #define OTHER 1 */
/* #define MICROSOFT 1 */
#include <stdio.h>
#include "defs.h"
#ifdef OTHER
#include <dos.h>
#endif
static int CURx = 0, CURy = 0; /* Current cursor location */
/* Structure for the c86 regs to be passed to sysint call */
#ifndef OTHER
typedef struct regs {
int ax, bx, cx, dx, si, di, ds, es;
} REG_ST;
#else
#ifndef MICROSOFT
typedef struct XREGS REG_ST;
#else
typedef struct WORDREGS REG_ST;
#endif
#define sysint(a,b,c) int86(a,b,c)
#endif
static REG_ST reg1, reg2;
static char mode, page, color, colorb;
static int OVALF = 0;
extern int rx1, rx2, ry1, ry2;
extern rect_t screen, *cur_win, *cur_port;
#define abs(x) ( ( x ) < 0 ? ( -x ) : ( x ) )
#define UP 1
#define DN 3
#define RT 4
#define LT 12
#define UPLT 13
#define UPRT 5
#define DNRT 7
#define DNLT 15
double do_d();
char get_move();
/*+1***************************************************************************/
/* */
/* initialize - Initializes the screen */
/* */
/* description - Sets the color to white, sets the screen to 320 x 200 */
/* graphics, draws a square around the screen, and sets */
/* the global screen window */
/* */
/* parameters - initialize() */
/* */
/* returns - NOTHING */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
initialize()
{
CURx = CURy = 0;
set_rect(&screen,0,0,319,199); /* set global screen rectangle */
cur_win = cur_port = &screen;
reg1.ax = 0x0f00; /* get finish values for terminate */
sysint(0x10,®1,®2);
page = reg2.bx >> 8; /* moniter page to reset to */
mode = reg2.ax; /* screen mode to reset to */
reg1.ax = 4;
sysint(0x10, ®1, ®2); /* set to 320 x 200 color graph mode */
set_color(WHITE);
line_to(319, 0); /* do screen rectangle */
line_to(319, 199);
line_to(0, 199);
line_to(0, 0);
}
/*+1***************************************************************************/
/* */
/* set_color - set the draw color */
/* */
/* description - sets the glogal drawing color - CAUTION: Most of the */
/* eight colors use 2 pixels per color. this is in color */
/* graphics mode, the IBM only gives you 4 colors, so */
/* I had to combine them in pairs to get all eight colors*/
/* */
/* parameters - get_color(col) */
/* int col; The color to be set to */
/* */
/* Returns - Nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
set_color(col)
int col;
{
switch(col)
{
case BLACK : /* set display's equivalent color code */
color = 0;
break;
case WHITE :
color = 15;
break;
case RED :
color = 2;
break;
case GREEN :
color = 5;
break;
case BLUE :
color = 8;
break;
case MAGENTA :
color = 10;
break;
case CYAN :
color = 4;
break;
case YELLOW :
color = 3;
break;
}
}
/*+1***************************************************************************/
/* */
/* terminate - Reset the system */
/* */
/* description - reset the system to the way it was before the */
/* initialize call */
/* */
/* parameters - terminate() */
/* */
/* returns - Nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
terminate()
{
reg1.ax = mode; /* reset the mode */
sysint(0x10, ®1, ®2);
if ( page ) /* if was on page other than 1 reset it */
{
reg1.ax = 0x500 | page;
sysint(0x10, ®1, ®2);
}
}
/*+1***************************************************************************/
/* */
/* line - Draw a line */
/* */
/* description - Draws a line from the current location to the */
/* location referenced by CURx + x, CURy + y. It also */
/* updated ( CURx, CURy ) to point to the end of the */
/* line. */
/* */
/* parameters - line(x,y) */
/* int x; The Dx to move */
/* int y; The Dy to move */
/* */
/* returns - Nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
line(x1,y1)
int x1,y1;
{
int x2, y2; /* The end point*/
int x, y;
int adx, ady; /* The Distance to move */
int xa, ya; /* The direction to move */
int d; /* The distance already moved */
int incr1, incr2; /* The distance moved each time */
int savx, savy;
if ( clipper ( CURx, CURy, x1 + CURx, y1 + CURy, cur_win ) )
{
savx = rx2;
savy = ry2;
map ( &rx1, &ry1 ); /* map to screen coordinates */
map ( &rx2, &ry2 );
colorb = ( color >> 2 ) & 3;
x = rx2 - rx1;
y = ry2 - ry1;
if ( x < 0 ) /* Set up to move backwards on the X-axis */
{
xa = -1;
adx = -x;
}
else /* Set up to move forwards on the X-axis */
{
xa = 1;
adx = x;
}
if ( y < 0 ) /* Set up to move backwards on the Y-axis */
{
ya = -1;
ady = -y;
}
else /* Set up to move forwards on the Y-axis */
{
ya = 1;
ady = y;
}
if (adx > ady) /* Are we moving more over than up */
{
incr1 = ady << 1;
d = incr1 - adx;
incr2 = incr1 - ( adx << 1 );
while ( rx1 != rx2 )
{
rx1 += xa;
if (d < 0)
d += incr1;
else
{
ry1 += ya;
d += incr2;
}
CURx = rx1;
CURy = ry1;
do_pix();
}
}
else /* Are we going more over than up */
{
incr1 = adx << 1;
d = incr1 - ady;
incr2 = incr1 - ( ady << 1 );
while ( ry1 != ry2 )
{
ry1 += ya;
if (d < 0)
d += incr1;
else
{
rx1 += xa;
d += incr2;
}
CURx = rx1;
CURy = ry1;
do_pix();
}
}
CURx = savx;
CURy = savy;
}
}
/*+1***************************************************************************/
/* */
/* line_to - Draw a line */
/* */
/* description - Draws a line from the current location to the */
/* location referenced by ( x, y ). It also updated */
/* ( CURx, CURy ) to point to the end of the */
/* line. */
/* */
/* parameters - line(x,y) */
/* int x; The Absolute position to move to */
/* int y; The Absolute position to move to */
/* */
/* returns - Nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
line_to(x,y)
int x,y;
{
line ( x - CURx, y - CURy ); /* Just convert to a relative move */
}
/*+1***************************************************************************/
/* */
/* text_bbox - sets bounding box for text */
/* */
/* description - sets the bounding box for a text string using the */
/* justifation given. */
/* */
/* parameters - text_bbox(string, jh, jv) */
/* char *string; string to bound */
/* char jh; horizontal justification */
/* char jv; vertical justification */
/* */
/* returns - a pointer ot a bounding box for the text string */
/* */
/* Porgrammer - Jeff Wrench */
/* */
/*-1***************************************************************************/
rect_t *text_bbox(string, jh, jv)
char *string, jh, jv;
{
int len;
rect_t *retval;
len = strlen(string) * 8; /* length in pixels of string */
retval = inst_rect(0, 0, len, 8); /* get rectangle for LEFT BOTTOM just */
switch ( (int) jh ) /* Justify it horizontially */
{
case MIDDLE:
offset_rect ( retval, ( - len ) / 2, 0 );
break;
case RIGHT:
offset_rect ( retval, - len, 0 );
break;
}
switch ( (int) jv ) /* justify it vertically */
{
case TOP:
offset_rect ( retval, 0, -8 );
break;
case CENTER:
offset_rect ( retval, 0, -4 );
break;
}
return ( retval ); /* return the bounding box */
}
/*+1***************************************************************************/
/* */
/* draw_text - draw a string on the screen */
/* */
/* description - Draws String at ( X, Y ) with justification */
/* */
/* parameters - draw_text(string, x, y, bbox); */
/* char *string; string to print */
/* int x, y; where to print the string */
/* rect_t *bbox; justification from text_bbox */
/* */
/* returns - nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
draw_text(string, x, y, bbox)
char *string;
int x, y;
rect_t *bbox;
{
int chrx, chry;
char *str;
x += bbox->left; /* get upper left of first character */
y += bbox->top;
/* map viewable bbox */
map( &x, &y); /* map to screen */
for ( str = string; *str; str++, x += 8 ) /* print the characters */
genchr(x, y, *str);
}
/*+1***************************************************************************/
/* */
/* fill_rect - Fills a rectangle */
/* */
/* description - Fills a rectangle after clipping it to the window */
/* */
/* parameters - fill_rect(rect_pointer) */
/* rect_t *rect_pointer rectangle to be filled */
/* */
/* returns - nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
fill_rect(rect_pointer)
rect_t *rect_pointer;
{
int i, j;
int savx, savy;
rect_t r;
savx = CURx;
savy = CURy;
if(sect_rect(rect_pointer, cur_win, &r)) /* clip the rectangle */
{
for ( i = r.bottom; i <= r.top; i++ ) /* fill one line at a time */
{
CURy = i;
CURx = r.left;
line_to ( r.right, CURy );
}
}
CURx = savx;
CURy = savy;
}
/*+1***************************************************************************/
/* */
/* clear_vport - clears the current view port */
/* */
/* description - clears the current view_port and redwaws the screen */
/* rectangle */
/* */
/* parameters - clear_vport(vport) */
/* vport_t *vport; the view port to be cleared */
/* */
/* returns - nothing */
/* */
/* programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
clear_vport(vport)
vport_t *vport;
{
int i, j;
char tmpcolor;
tmpcolor = color;
i = CURx;
j = CURy;
set_color(vport->bkgnd);
fill_rect ( vport->bitmap ); /* fill the view port wigh background */
set_color(vport->brder);
CURx = vport->bitmap->left;
CURy = vport->bitmap->top;
/* draw the boarder */
line_to(vport->bitmap->right, vport->bitmap->top);
line_to(vport->bitmap->right, vport->bitmap->bottom);
line_to(vport->bitmap->left, vport->bitmap->bottom);
line_to(vport->bitmap->left, vport->bitmap->top);
CURx = i;
CURy = j;
color = tmpcolor;
}
/*+1***************************************************************************/
/* */
/* fill_oval - fills an oval */
/* */
/* description - Fills an oval bounded by rect_pointer, It calls */
/* frame_oval() to save code */
/* */
/* parameters - fill_oval ( rect_pointer ) */
/* rect_t *rect_pointer; bounting box of oval to fill */
/* */
/* returns - nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
fill_oval(rect_pointer)
rect_t *rect_pointer;
{
OVALF = 1; /* say we're filling */
frame_oval(rect_pointer); /* do the fill */
OVALF = 0; /* go back to default frame */
}
/*+1***************************************************************************/
/* */
/* frame_oval - frames an oval */
/* */
/* description - Frames an oval bounded by rect_pointer. */
/* */
/* parameters - fill_oval ( rect_pointer ) */
/* rect_t *rect_pointer; bounting box of oval to fill */
/* */
/* returns - nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
frame_oval(rect_pointer)
rect_t *rect_pointer;
{
int x, y, alpha, beta, u, v;
long k;
long k1, k2, k3, a, b;
long d;
int *coord1, *coord2, *coord3, d1, d2, d3;
int w;
int count;
int oldx, oldy;
int xoff, yoff;
int left, right, top, bottom;
int xcent, ycent;
rect_t r;
if(sect_rect(rect_pointer, cur_win, &r)) /* clip it down if needed */
{
map( &(r.left), &(r.bottom)); /* map to screen */
map( &(r.right), &(r.top));
/* xoff is the distance from the left to center of oval */
xoff = ( ( r.right - r.left ) / 2 ) + r.left;
/* yoff is the distance from the top to center of oval */
yoff = ( ( r.bottom - r.top ) / 2 ) + r.top;
/*make center relative 0,0 */
xcent = ycent = 0;
/* move bounding box so the center is relative at 0,0 */
offset_rect ( &r, - xoff, - yoff );
left = r.left;
right = r.right;
top = r.top;
bottom = r.bottom;
/* ellipse is calculated by by the formula (x*x)/(a*a) + (y*y)/(b*b) = 1 */
/* so I plug the point above the current into the formula and the point */
/* to the right of the current into the formula and the one closest to 1 */
/* is the next point on the ellipse */
set_d(&r); /* set A squared and B squares */
x = left;
oldy = y = 0;
CURx = x + xoff;
CURy = yoff;
/* draw the fisrt line or first 2 point of the ellipse */
if ( OVALF )
hline ( CURx, ( xoff * 2 ) - CURx, CURy );
else
{
int disx, disy;
disx = 2 * ( xoff - CURx );
disy = 2 * ( yoff - CURy );
do_pix();
CURx += disx;
do_pix();
}
while ( x < 0 )
{
d1 = do_d (x + 1, y ); /* plug next possible point into formula */
d2 = do_d (x, y + 1 );
if ( d1 < d2 ) /* whic one is closest */
x++;
else
y++;
CURx = x + xoff; /* set next point relative ot screen */
CURy = yoff + y;
if ( OVALF )
{
/* draw the line */
if ( oldy == y ) continue;
hline ( CURx, ( xoff * 2 ) - CURx, CURy );
CURx = x + xoff;
CURy -= ( abs ( CURy - yoff ) * 2 );
/* mirror the line around the x-axis */
hline ( CURx, ( xoff * 2 ) - CURx, CURy );
oldy = y;
}
else
{
int disx, disy;
disx = 2 * ( xoff - CURx );
disy = 2 * ( yoff - CURy );
/* plot a point in each qradrant */
do_pix();
CURx += disx;
do_pix();
CURy += disy;
do_pix();
CURx -= disx;
do_pix();
}
}
}
}
/***********************************/
/* hiline prints a horizontal line */
/***********************************/
hline( x1, x2, y )
int x1, x2, y;
{
CURy = y;
for ( CURx = x1; CURx <= x2; CURx++ )
do_pix();
}
static double a, b;
/******************************************************************/
/* set_d - computes A squared and B squared for the given ellipse */
/******************************************************************/
static set_d ( r )
rect_t *r;
{
double tmp;
tmp = (double) ( ( - r->left ) + r->right ) / 2.0;
a = tmp * tmp;
tmp = (double) ( ( - r->top ) + r->bottom ) / 2.0;
b = tmp * tmp;
}
/******************************************************************************/
/* do_d - plugs the given point into the ellipse form and returns the answer */
/******************************************************************************/
static double do_d( x, y )
int x, y;
{
return ( abs ( ( (double) ( x * x ) / a ) + ( (double) ( y * y ) / b ) ) );
}
static int fence;
/*+1***************************************************************************/
/* */
/* fill_poly - fills the polygon */
/* */
/* description - fills the given polygon by building a move table of */
/* the polygon, then feeds it into the fill algorithm. */
/* The fill algorithm works by xoring a line from the */
/* bounding box to current point on the polygon. All */
/* points on the inside are xored an odd number of times */
/* so they stay the color while point on the outside are */
/* xored en eved number of times so they return to the */
/* original color. */
/* */
/* parameters - fill_poly(poly); */
/* poly_t *poly; polygon to be filled */
/* */
/* returns - nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
fill_poly(poly_pointer)
poly_t *poly_pointer;
{
char table[4000], *p = table, move;
int x, y, n, i;
build_tab(poly_pointer, table);
x = poly_pointer->point->point.x; /* get starting point */
y = poly_pointer->point->point.y;
n = 1;
p = table;
for ( move = get_move( &n, &p ); move; /* move until finished with poly */
move = get_move( &n, &p ) )
{
switch ( move )
{
case RT: /* move right */
x++;
break;
case LT: /* move left */
x--;
break;
case UP: /* move up */
clr_line( x, y++ );
break;
case DN: /* move down */
clr_line( x, --y );
break;
case UPRT: /* move up right */
clr_line( ++x, y++ );
break;
case UPLT: /* move up left */
clr_line( --x, y++ );
break;
case DNRT: /* move down right */
clr_line( ++x, --y );
break;
case DNLT: /* move down left */
clr_line( --x, --y );
break;
}
}
}
/**************************************************/
/* clr_line - xor's a line with the current color */
/**************************************************/
clr_line( x, y )
{
int i;
for ( i = fence; i < x; i++ )
xor_pix ( i, y );
}
/*+1***************************************************************************/
/* */
/* build_tab - Builds a move table */
/* */
/* description - Builds a move table */
/* */
/* parameters - build_table( poly, table ); */
/* poly_t *poly; poly to build */
/* char *table; table to put moves */
/* */
/* returns - nothing */
/* */
/* programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
build_tab ( poly, table )
poly_t *poly;
char *table;
{
int x1, x2, y1, y2, n = 1;
int ox1 = -1, ox2 = -1, oy1 = -1, oy2 = -1;
int cd1, cd2, point_in;
char *p;
cpoint_t *np, *sp, *bp, *ep, *lp;
p = table;
/* are there two point on the polygon */
if ( ( ! poly ) || ( ! poly->point ) || ( ! poly->point->next ) ) /* no */
{
table[0] = 0;
return;
}
x2 = poly->point->point.x; /* get first point */
y2 = poly->point->point.y;
fence = x2;
for ( np = poly->point->next; np; np = np->next )
{
x1 = x2; /* reset first point to old last point */
y1 = y2;
x2 = np->point.x; /* get the new last point */
y2 = np->point.y;
do_line(x1, y1, x2, y2, &p, &n); /* do the line */
}
*(++p) = '\0'; /* end table with a null */
}
/*+1***************************************************************************/
/* */
/* do_line - builds a line of moves */
/* */
/* description - builds a line of moves and puts them in the table */
/* the algorithm is the same as line() */
/* */
/* parameters - do_line ( x1, y1, x2, x2, p, n ) */
/* int x1, y1; starting point */
/* int x2, y2; ending point */
/* char **p; pointer to pointer into the table */
/* */
/* returns - nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
do_line(x1, y1, x2, y2, p, n)
int x1, y1, x2, y2, *n;
char **p;
{
int xprev, yprev, byts;
int dx, dy, adx, ady, xa, ya, d, incr1, incr2;
if ( fence > x2 ) fence = x2;
xprev = x1;
yprev = y1;
dx = x2-x1;
dy = y2-y1;
if ( dx < 0 ) /* Set up to move backwards on the X-axis */
{
xa = -1;
adx = -dx;
}
else /* Set up to move forwards on the X-axis */
{
xa = 1;
adx = dx;
}
if ( dy < 0 ) /* Set up to move backwards on the Y-axis */
{
ya = -1;
ady = -dy;
}
else /* Set up to move forwards on the Y-axis */
{
ya = 1;
ady = dy;
}
if (adx > ady)
{
incr1 = ady << 1;
incr2 = (d = incr1 - adx) - adx;
do
{
x1 += xa;
if (d < 0)
d += incr1;
else
{
y1 += ya;
d += incr2;
}
**p = do_move(x1-xprev,y1-yprev,**p,n);
xprev = x1;
yprev = y1;
if ( *n )
{
*(++(*p)) = '\0';
++byts;
}
} while (x1 != x2);
}
else
{
incr1 = adx << 1;
incr2 = (d = incr1 - ady) - ady;
do
{
y1 += ya;
if (d < 0)
d += incr1;
else
{
x1 += xa;
d += incr2;
}
**p = do_move(x1-xprev,y1-yprev,**p,n);
xprev = x1;
yprev = y1;
if ( *n )
{
*(++(*p)) = '\0';
++byts;
}
} while (y1 != y2);
}
}
/*+1***************************************************************************/
/* */
/* do_move - does one pixel move */
/* */
/* description - does a one pixel move */
/* */
/* parameters - do_move ( dx, dy, curbyt, n ) */
/* int dx, dy; direction of move */
/* int curbyt; the cyrrent byte of the table */
/* int *n; which nibble to put move in */
/* */
/* returns - The new byte for the table */
/* */
/* programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
do_move(dx,dy,curbyt,n)
int dx, dy, *n, curbyt;
{
unsigned int nibble;
nibble = 0;
if (dx)
{
if (dx < 0)
nibble = 0x0c;
else
nibble = 0x04;
}
if (dy)
{
if (dy < 0)
nibble |= 0x03;
else
nibble |= 0x01;
}
/* put the move into the proper nibble */
nibble = (*n) ? (nibble << 4) : (curbyt & 0xfff0 ) | nibble;
if (*n)
*n = 0;
else
*n = 1;
return (nibble);
}
/*+1***************************************************************************/
/* */
/* get_move - gets the next move */
/* */
/* description - gets the next move from the move table */
/* */
/* parameters - get_move ( n, p ) */
/* int *n; which nibble to use */
/* char **p; pointer to a pointer into the table */
/* */
/* returns - the new move */
/* */
/* programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
char get_move( n, p )
int *n;
char **p;
{
char *p1, nibble;
p1 = *p;
nibble = *p1;
if ( *n ) /* get right nibble */
{
nibble = ( nibble >> 4 ) & 0x0f;
*n = 0;
}
else
{
nibble &= 0x0f;
*n = 1;
(*p)++; /* if last nibble inc to byte of table */
}
return (nibble);
}
/*+1***************************************************************************/
/* */
/* do_pix - Does a pixel */
/* */
/* description - Turns the given pixel to the current set_color */
/* */
/* parmeters - do_pix () */
/* */
/* returns - Nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
do_pix()
{
if ( CURx & 1 )
colorb = ( color >> 2 ) & 3;
else
colorb = color & 3;
reg1.ax = 0xc00 | colorb;
reg1.cx = CURx;
reg1.dx = CURy;
sysint( 0x10, ®1, ®2 );
}
/*+1***************************************************************************/
/* */
/* xor_pix - Does a pixel */
/* */
/* description - Turns the given pixel to the current set_color */
/* after clipping the pixel */
/* */
/* parameters - xor_pix( x, y ) */
/* */
/* returns - Nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
xor_pix( x, y )
int x, y;
{
if ( clip_code ( x, y, cur_win ) ) /* is pixel in window */
return; /* no */
map ( &x, &y ); /* map to screen */
if ( x & 1 )
colorb = ( color >> 2 ) & 3;
else
colorb = color & 3;
reg1.ax = 0xc80 | colorb;
reg1.cx = x;
reg1.dx = y;
sysint( 0x10, ®1, ®2 );
}
/*+1***************************************************************************/
/* */
/* genchr - getnerates a character */
/* */
/* description - generates a character at the given position, I use */
/* instead of BIOS because I want to start a character */
/* anywhere on screen/ */
/* */
/* parameters - genchr( x, y, chr ) */
/* int x, y; position of upper left of character */
/* char chr; character to print */
/* */
/* returns - nothing */
/* */
/* Programmer - Jeff Wrench */
/* */
/*-1***************************************************************************/
genchr ( x, y, chr )
int x, y;
char chr;
{
unsigned pos, seg;
int i, j;
int chrtodo[8];
int savx, savy;
savx = CURx;
savy = CURy;
if ( chr < 128 )
{
pos = (int) chr << 3; /* mult by 8 because 8 bytes per char */
pos += 0xfa6e; /* BIOS character table for first 128 chars */
seg = 0xf000;
}
else
{
pos = ( (int) chr - 128 ) << 3; /* mult by 8 because 8 bytes per char */
pos += peek ( 0x1f * 4, 0 );
seg = peek ( ( 0x1f * 4 ) + 2, 0 );
}
for ( i = 0; i < 8; i++ ) /* read the char into memory */
chrtodo[i] = peek ( pos + i, seg ) & 0xff;
for ( i = 0; i < 8; i++ ) /* eight lines per char of */
for ( j = 0; j < 8; j++ ) /*eight bits across */
{
chrtodo[i] <<= 1;
if ( chrtodo[i] & 0x100 ) /* is this bit on */
{ /* if so turn the pixel on */
CURx = x + j;
CURy = y + i;
do_pix();
}
}
CURx = savx;
CURy = savy;
}
/**********************************************/
/* move_to - moves current position to (x, y) */
/**********************************************/
move_to(x, y)
int x, y;
{
CURx = x;
CURy = y;
}
/***************************************************************/
/* move - moves current position to (x + current, y + current) */
/***************************************************************/
move(x, y)
int x, y;
{
CURx += x;
CURy += y;
}
#ifdef MICROSOFT
/*
* provide an equivalent peek function for Microsoft
*/
int peek(offset, segment)
int offset, segment;
{
int far *ip;
ip = (int far *)((long)segment * 65536l + (long)offset);
return(*ip);
}
#endif